/**
 * @fileOverview
 * @exports Controller as org.puremvc.js.core.Controller
 * @imports org.puremvc.js.core.View
 * @imports org.puremvc.js.patterns.observer.Observer
 */

/**
 * @constructor
 * @throws {Error}
 */
function Controller ()
{
	if (Controller.instance != null)
	{
		throw new Error (Controller.SINGLETON_MSG);
	}
	
	Controller.instance= this;
	this.commandMap= {};
	this.initializeController();
};

/**
 * @protected
 * @return {void}
 */
Controller.prototype.initializeController= function ()
{
	this.view= View.getInstance();
};

/**
 * @static
 * @return {Controller}
 * @throws {Error}
 */
Controller.getInstance= function ()
{
	if (null == Controller.instance)
	{
		Controller.instance= new Controller;
	}
	
	return Controller.instance;
};

/**
 * @param {Notification} note
 * @return {void}
 */
Controller.prototype.executeCommand= function (note)
{
	var commandClassRef= this.commandMap[note.getName()]
	,	command
	
	if (null == commandClassRef)
	{
		return;
	}
	
	command= new commandClassRef;
	command.execute(note);
};

/**
 * @param {string} notificationName
 * @param {Function} commandClassRef
 * @return {void}
 */
Controller.prototype.registerCommand= function (notificationName, commandClassRef)
{
	if (null == this.commandMap[notificationName])
	{
		this.view.registerObserver(notificationName, new Observer(this.executeCommand, this));
	}
	
	this.commandMap[notificationName]= commandClassRef;
};

/**
 * @param {string} notificationName
 * @return {boolean}
 */
Controller.prototype.hasCommand= function (notificationName)
{
	return null != this.commandMap[notificationName];
};

/**
 * @param {string} notificationName
 * @return {void}
 */
Controller.prototype.removeCommand= function (notificationName)
{
	if (this.hasCommand(notificationName))
	{
		this.view.removeObserver(notificationName, this);
		this.commandMap[notificationName]= null;
	}
}

/**
 * @protected
 * @type {View}
 */
Controller.prototype.view= null;

/**
 * @protected
 * @type {Object}
 */
Controller.prototype.commandMap= null;

/**
 * @protected
 * @static
 * @type {Controller}
 */
Controller.instance= null;

/**
 * @protected
 * @static
 * @const
 * @type {string}
 */
Controller.SINGLETON_MSG= "Controller Singleton already constructed";
